<template>
  <div class="table-toolbar">

    <!--顶部左侧区域-->
    <div class="flex items-center table-toolbar-left ">
      <template v-if="title">
        <div class="table-toolbar-left-title">
          {{ title }}
          <n-tooltip trigger="hover" v-if="titleTooltip">
            <template #trigger>
              <n-icon size="18" class="ml-1 cursor-pointer text-gray-400">
                <QuestionCircleOutlined/>
              </n-icon>
            </template>
            {{ titleTooltip }}
          </n-tooltip>
        </div>
      </template>
      <slot name="tableTitle"></slot>
    </div>

    <div class="flex items-center table-toolbar-right">

      <!--顶部右侧区域-->
      <slot name="toolbar"></slot>

      <!--刷新-->
      <n-tooltip trigger="hover">
        <template #trigger>
          <div class="table-toolbar-right-icon" @click="reload">
            <n-icon size="18">
              <ReloadOutlined/>
            </n-icon>
          </div>
        </template>
        <span>刷新</span>
      </n-tooltip>

      <!--密度-->
      <n-tooltip trigger="hover">
        <template #trigger>
          <div class="table-toolbar-right-icon">
            <n-dropdown @select="densitySelect" trigger="click" :options="densityOptions" v-model:value="tableSize">
              <n-icon size="18">
                <ColumnHeightOutlined/>
              </n-icon>
            </n-dropdown>
          </div>
        </template>
        <span>密度</span>
      </n-tooltip>

      <!--表格设置单独抽离成组件-->
      <ColumnSetting></ColumnSetting>

    </div>

  </div>
  <div class="s-table">
    <n-data-table
        v-bind="getBindValues"
        :pagination="pagination"
        @update:page="updatePage"
        @update:page-size="updatePageSize"
    >
      <template #[item]="data" v-for="item in Object.keys($slots)" :key="item">
        <slot :name="item" v-bind="data"></slot>
      </template>
    </n-data-table>
  </div>
</template>

<script lang="ts">
import { NDataTable } from 'naive-ui'
import { ref, defineComponent, reactive, unref, onMounted, toRaw, onBeforeMount, computed, toRefs, watch } from "vue"
import { ReloadOutlined, ColumnHeightOutlined, SettingOutlined, DragOutlined, QuestionCircleOutlined } from '@vicons/antd'
import { createTableContext } from './hooks/useTableContext';

import ColumnSetting from './components/settings/ColumnSetting.vue'

import { useLoading } from './hooks/useLoading';
import { useColumns } from './hooks/useColumns';
import { useDataSource } from './hooks/useDataSource';
import { usePagination } from './hooks/usePagination';

import { basicProps } from './props'

import { BasicTableProps } from './types/table'


const densityOptions = [
  {
    type: "menu",
    label: '紧凑',
    key: 'small',
  },
  {
    type: "menu",
    label: '默认',
    key: "medium"
  },
  {
    type: "menu",
    label: '宽松',
    key: 'large'
  }
]

export default defineComponent({
  components: {
    ReloadOutlined, ColumnHeightOutlined, SettingOutlined, DragOutlined, ColumnSetting, QuestionCircleOutlined
  },
  props: {
    ...NDataTable.props, // 这里继承原 UI 组件的 props
    ...basicProps
  },
  emits: [
    'fetch-success',
    'fetch-error',
    'update:checked-row-keys'
  ],
  setup(props, { emit }) {

    const wrapRef = ref<Nullable<HTMLDivElement>>(null);

    const tableData = ref<Recordable[]>([]);
    const innerPropsRef = ref<Partial<BasicTableProps>>();

    const getProps = computed(() => {
      return { ...props, ...unref(innerPropsRef) } as BasicTableProps;
    });

    const { getLoading, setLoading } = useLoading(getProps);

    const {
      getPaginationInfo,
      getPagination,
      setPagination,
      setShowPagination,
      getShowPagination,
    } = usePagination(getProps)

    const { getDataSourceRef, getRowKey, getDataSource, setDataSource, reload } = useDataSource(
        getProps, {
          getPaginationInfo,
          setPagination,
          tableData,
          setLoading
        }, emit
    )

    const {
      getPageColumns,
      setColumns,
      getColumns,
      getCacheColumns,
      setCacheColumnsField,
      getColumnsRef
    } = useColumns(getProps)

    const state = reactive({
      tableSize: 'medium',
      isColumnSetting: false
    })

    //页码切换
    function updatePage(page) {
      setPagination({ page: page, });
      reload()
    }

    //分页数量切换
    function updatePageSize(size) {
      setPagination({ page: 1, pageSize: size, });
      reload()
    }

    //密度切换
    function densitySelect(e) {
      state.tableSize = e
    }

    //选中行
    function updateCheckedRowKeys(rowKeys) {
      emit('update:checked-row-keys', rowKeys)
    }

    //重置 Columns
    const resetColumns = () => {
      columns.map(item => {
        item.isShow = true
      })
    }

    //获取表格大小
    const getTableSize = computed(() => state.tableSize)

    //组装表格信息
    const getBindValues = computed(() => {
      const tableData = unref(getDataSourceRef);
      let propsData = {
        ...unref(getProps),
        loading: unref(getLoading),
        columns: toRaw(unref(getPageColumns)),
        rowKey: unref(getRowKey),
        data: tableData,
        size: unref(getTableSize),
        remote: true
      }
      return propsData
    })

    //获取分页信息
    const pagination = computed(() => toRaw(unref(getPaginationInfo)))

    function setProps(props: Partial<BasicTableProps>) {
      innerPropsRef.value = { ...unref(innerPropsRef), ...props };
    }

    const tableAction: TableActionType = {
      reload,
      setColumns,
      setLoading,
      setProps,
      getColumns,
      getPageColumns,
      getCacheColumns,
      setCacheColumnsField,
      emit,
      getSize: () => {
        return unref(getBindValues).size as SizeType;
      },
    };

    createTableContext({ ...tableAction, wrapRef, getBindValues });

    return {
      ...toRefs(state),
      getBindValues,
      densityOptions,
      reload,
      densitySelect,
      updatePage,
      updatePageSize,
      updateCheckedRowKeys,
      pagination,
      resetColumns,
      tableAction
    }
  }
})

</script>
<style lang='less' scoped>
.table-toolbar {
  display: flex;
  justify-content: space-between;
  padding: 0 0 16px 0;

  &-left {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    flex: 1;

    &-title {
      display: flex;
      align-items: center;
      justify-content: flex-start;
      font-size: 16px;
      font-weight: 600;
    }
  }

  &-right {
    display: flex;
    justify-content: flex-end;
    flex: 1;

    &-icon {
      margin-left: 12px;
      font-size: 16px;
      cursor: pointer;
      color: var(--text-color);

      :hover {
        color: #1890ff;
      }
    }
  }
}

.table-toolbar-inner-popover-title {
  padding: 2px 0;
}
</style>
